package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"time"

	"github.com/sirupsen/logrus"
)

type Exercise struct {
	num1   int
	num2   int
	op     string
	answer int
	expr   string // 用于去重的唯一标识
}

func main() {
	rand.Seed(time.Now().UnixNano())
	logrus.Info("-------加减法口算练习系统-v0.3（50道）-----")
	logrus.Info("规则：无重复算式，加法和减法各25道，加法和≤100，减法差≥0\n")

	scanner := bufio.NewScanner(os.Stdin)
	correctCount := 0
	total := 50
	addCount := total / 2 // 加法25道
	subCount := total - addCount // 减法25道（明确使用该变量）

	generated := make(map[string]bool)
	var exercises []Exercise

	// 1. 生成指定数量的加法算式（使用addCount控制）
	for len(exercises) < addCount {
		ex := generateAddExercise()
		if !generated[ex.expr] {
			generated[ex.expr] = true
			exercises = append(exercises, ex)
		}
	}

	// 2. 生成指定数量的减法算式（使用subCount控制，逻辑更清晰）
	// 此时exercises已有addCount道题，需要再生成subCount道
	targetAfterSub := addCount + subCount
	for len(exercises) < targetAfterSub {
		ex := generateSubExercise()
		if !generated[ex.expr] {
			generated[ex.expr] = true
			exercises = append(exercises, ex)
		}
	}

	// 打乱顺序
	rand.Shuffle(len(exercises), func(i, j int) {
		exercises[i], exercises[j] = exercises[j], exercises[i]
	})

	// 逐题答题
	for i, ex := range exercises {
		fmt.Printf("第%d题：%d %s %d = ?\n", i+1, ex.num1, ex.op, ex.num2)
		fmt.Print("请输入答案：")

		var userAns int
		_, err := fmt.Scan(&userAns)
		if err != nil {
			scanner.Scan()
			fmt.Println("输入错误，请输入整数！本题按错误处理。\n")
			continue
		}

		if userAns == ex.answer {
			fmt.Println("回答正确！")
			correctCount++
		} else {
			fmt.Printf("回答错误，正确答案是：%d\n", ex.answer)
		}
		fmt.Println("------------------------")
	}

	logrus.Infof("练习结束！共%d题，正确%d题，正确率：%.2f%%",
		total, correctCount, float64(correctCount)/float64(total)*100)
}

// 生成合法加法算式
func generateAddExercise() Exercise {
	for {
		num1 := rand.Intn(100)
		num2 := rand.Intn(100)
		sum := num1 + num2
		if sum <= 100 {
			expr := fmt.Sprintf("%d+%d", num1, num2)
			return Exercise{num1, num2, "+", sum, expr}
		}
	}
}

// 生成合法减法算式
func generateSubExercise() Exercise {
	for {
		num1 := rand.Intn(100)
		num2 := rand.Intn(100)
		if num1 >= num2 {
			diff := num1 - num2
			expr := fmt.Sprintf("%d-%d", num1, num2)
			return Exercise{num1, num2, "-", diff, expr}
		}
	}
}